﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Diagnostics;
using System.Threading;
using Intorise.Framework;
using Config;

namespace Intorise.Net
{
    public class Adsl
    {
        private static Security security = new Security();
        bool isCheckNetStatus = true;
        bool isCheckIp = false;
        int checkNetStatusSpanMilliseconds = 2000;
        int checkNetStatusCount = 3;
        int checkIPCount = 3;

        NetTools common = new NetTools();

        public Adsl()
        {
            ConnectionName = ConfigManager.AdslConnectionName;
            Password = ConfigManager.AdslPassword;
            Username = ConfigManager.AdslUserName;
            RouterConnectUrl = ConfigManager.ApplicationConfig.RouterConnectUrl;
            RouterDisconnectUrl = ConfigManager.ApplicationConfig.RouterDisconnectUrl;
            RouterAdminUsername = ConfigManager.ApplicationConfig.RouterAdminUsername;
            RouterAdminPassword = ConfigManager.ApplicationConfig.RouterAdminPassword;
            DialUpType = ConfigManager.ApplicationConfig.ChangeIpType;
            checkNetStatusCount = ConfigManager.ApplicationConfig.CheckNetStatusCount;
            ConnectDelay = 5;
        }
        public Adsl(string connectionName, string username, string password)
            : this()
        {
            ConnectionName = connectionName;
            Username = username;
            Password = password;
        }
        public Adsl(string routerConnectUrl, string routerDisconnectUrl, string routerAdminUsername, string roterAdminPassword)
            : this()
        {
            RouterDisconnectUrl = routerConnectUrl;
            RouterConnectUrl = routerDisconnectUrl;
            RouterAdminUsername = routerAdminUsername;
            RouterAdminPassword = roterAdminPassword;
        }

        public string ConnectionName { get; set; }
        public string Username { get; set; }
        public string Password { get; set; }
        public string RouterDisconnectUrl { get; set; }
        public string RouterConnectUrl { get; set; }
        public string RouterAdminUsername { get; set; }
        public string RouterAdminPassword { get; set; }
        public bool IsCheckNetStatus
        {
            get { return isCheckNetStatus; }
            set { isCheckNetStatus = value; }
        }
        public int CheckNetStatusCount
        {
            get { return checkNetStatusCount; }
            set { checkNetStatusCount = value; }
        }
        public int CheckNetStatusTimespan
        {
            get { return checkNetStatusSpanMilliseconds; }
            set { checkNetStatusSpanMilliseconds = value; }
        }
        public bool IsCheckIp
        {
            get { return isCheckIp; }
            set { isCheckIp = value; }
        }
        public int CheckIPCount
        {
            get { return checkIPCount; }
            set { checkIPCount = value; }
        }
        public ConnectTypeEnum DialUpType { get; set; }
        public int ConnectDelay { get; set; }

        /// <summary>
        /// 登录路由器重新拨号
        /// </summary>
        public void RouterReconnect()
        {
            HttpWebRequest request = null;
            HttpWebResponse response = null;

            try
            {
                request = (HttpWebRequest)HttpWebRequest.Create(RouterDisconnectUrl);
                request.Method = "GET";
                request.ContentType = "application/x-www-form-urlencoded";
                request.Credentials = CredentialCache.DefaultCredentials;

                //获得用户名密码的Base64编码
                string code = Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", RouterAdminUsername, RouterAdminPassword)));

                //添加Authorization到HTTP头
                request.Headers.Add("Authorization", "Basic " + code);
                response = (HttpWebResponse)request.GetResponse();
                request.Abort();
                response.Close();


                Console.WriteLine("登录路由器进行ppoe连接...");
                request = (HttpWebRequest)HttpWebRequest.Create(this.RouterConnectUrl);
                request.Method = "GET";
                request.ContentType = "application/x-www-form-urlencoded";
                request.Credentials = CredentialCache.DefaultCredentials;

                //添加Authorization到HTTP头
                request.Headers.Add("Authorization", "Basic " + code);
                response = (HttpWebResponse)request.GetResponse();
                request.Abort();
                response.Close();
                Console.WriteLine("OK");
            }
            catch (Exception ex)
            {
                if (response != null)
                {
                    response.Close();
                }
                if (request != null)
                {
                    request.Abort();
                }
                Console.WriteLine(ex.Message);
            }
        }

        public void RouterDisconnect()
        {
            HttpWebRequest request = null;
            HttpWebResponse response = null;

            try
            {
                request = (HttpWebRequest)HttpWebRequest.Create(RouterDisconnectUrl);
                request.Method = "GET";
                request.ContentType = "application/x-www-form-urlencoded";
                request.Credentials = CredentialCache.DefaultCredentials;

                //获得用户名密码的Base64编码
                string code = Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", RouterAdminUsername, RouterAdminPassword)));

                //添加Authorization到HTTP头
                request.Headers.Add("Authorization", "Basic " + code);
                response = (HttpWebResponse)request.GetResponse();
                request.Abort();
                response.Close();
                Console.WriteLine("登录路由器断开ppoe连接...OK");
            }
            catch (Exception ex)
            {
                if (response != null)
                {
                    response.Close();
                }
                if (request != null)
                {
                    request.Abort();
                }
                Console.WriteLine(ex.Message);
            }
        }

        public void RouterConnect()
        {
            HttpWebRequest request = null;
            HttpWebResponse response = null;

            try
            {
                request = (HttpWebRequest)HttpWebRequest.Create(this.RouterConnectUrl);
                request.Method = "GET";
                request.ContentType = "application/x-www-form-urlencoded";
                request.Credentials = CredentialCache.DefaultCredentials;
                //获得用户名密码的Base64编码
                string code = Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", RouterAdminUsername, RouterAdminPassword)));
                //添加Authorization到HTTP头
                request.Headers.Add("Authorization", "Basic " + code);
                response = (HttpWebResponse)request.GetResponse();
                request.Abort();
                response.Close();
                Console.WriteLine("登录路由器进行ppoe连接...OK");
            }
            catch (Exception ex)
            {
                if (response != null)
                {
                    response.Close();
                }
                if (request != null)
                {
                    request.Abort();
                }
                Console.WriteLine(ex.Message);
            }
        }

        /// <summary>
        /// 本地拨号
        /// </summary>
        public bool LocalConnect()
        {
            Console.WriteLine("开始本地拨号...");
            string syspath = Environment.GetFolderPath(Environment.SpecialFolder.System);
            string result = "";

            Process p2 = new Process();
            //p2.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            Console.Out.WriteLine("断开当前连接...");
            p2.StartInfo.FileName = syspath + @"\RASDIAL.exe";
            p2.StartInfo.Arguments = "/disconnect";
            p2.StartInfo.UseShellExecute = false;
            p2.StartInfo.RedirectStandardError = true;
            p2.StartInfo.RedirectStandardInput = true;
            p2.StartInfo.RedirectStandardOutput = true;
            p2.Start();
            Console.Out.WriteLine(p2.StandardOutput.ReadToEnd());
            p2.WaitForExit();
            Console.Out.Write("断开当前连接...");
            Console.WriteLine("OK");

            Thread.Sleep(ConnectDelay * 1000);
            Process p = new Process();
            //p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            Console.Out.WriteLine("开始拨号...");
            p.StartInfo.FileName = syspath + @"\RASDIAL.exe";
            p.StartInfo.Arguments = ConnectionName + " " + Username + " " + Password;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.Start();

            result = p.StandardOutput.ReadToEnd();
            Console.Out.WriteLine(result);
            p.WaitForExit();
            if (result.Contains("错误"))
            {
                Console.WriteLine("拨号没有成功");
                return false;
            }
            else
            {
                Console.Out.Write("拨号..."); Console.WriteLine("OK");
            }
            return true;
        }

        /// <summary>
        /// 连接网络
        /// </summary>
        public bool Connect()
        {
            var result = true;
            if (DialUpType == ConnectTypeEnum.LocalDialUp)
            {
                result=LocalConnect();
            }
            else
            {
                RouterReconnect();
            }

            if (!result)
            {
                return false;
            }

            if (isCheckNetStatus)
            {
                for (int i = 0; i < CheckNetStatusCount; i++)
                {
                    Thread.Sleep(checkNetStatusSpanMilliseconds);
                    if (common.CheckNetStatus())
                    {
                        return true;
                    }
                }
                return false;
            }
            else
            {
                return true;
            }
        }

        /// <summary>
        /// 连接网络，并检测重复IP
        /// </summary>
        /// <returns></returns>
        public bool ConnectAndCheckIP()
        {
            if (isCheckIp)
            {
                Console.WriteLine("开始检测重复IP...检测次数：" + CheckNetStatusCount);
                for (int i = 0; i < CheckNetStatusCount; i++)
                {
                    string oldIP = NetTools.GetIP();
                    string newIP = "";

                    if (!Connect())
                    {
                        return false;
                    }

                    newIP = NetTools.GetIP();
                    Console.Out.WriteLine("原始IP为.." + oldIP);
                    Console.Out.WriteLine("新的IP为.." + newIP);
                    if (oldIP != newIP)
                    {
                        Console.Out.WriteLine("获取了新的IP.");
                        Console.WriteLine("检测重复IP结束");
                        return true;
                    }
                    Console.WriteLine("获取到重复的IP");
                }
                Console.WriteLine("检测重复IP结束" + checkIPCount + "，没有获取到不重复的IP...");
                return false;
            }
            else
            {
                return Connect();
            }
        }
    }
}
